package dm.bsi;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.dom4j.DocumentException;

import indi.zjh.dp.db.Session;
import indi.zjh.dp.error.ConfigureInvalidException;
import indi.zjh.dp.error.UnsuportedFieldException;
import indi.zjh.dp.orm.Relation;
import indi.zjh.dp.type.String256;

public class Deployment extends LogNode {
	public static final int MODE_WORKER = 0; // 模式: 只有无状态的工作节点
	public static final int MODE_MASTER_SLAVE = 1; // 模式: 主从模式
	public static final int MODE_MASTER_SLAVE_SENTINEL = 2; // 模式: 哨兵主从模式
	protected String name = "nil";
	protected String256 description = new String256("nil");
	protected int hostPort = 0;
	protected int secondHostPort = 0;
	protected int containerPort = 0;
	protected int curContainerPort = 0;
	protected int curId = 1;
	protected int mode = 0;
	protected int tryCount = 0;
	
	protected Relation service = new Relation(Service.class, Relation.ONE);
	protected Relation image = new Relation(Image.class, Relation.ONE);
	
	/**
	 * 获取关联的Image对象
	 * @param session
	 * @return
	 * @throws Exception 
	 * @throws DocumentException 
	 * @throws UnsuportedFieldException 
	 */
	public Image getImage(Session session) throws UnsuportedFieldException, DocumentException, Exception
	{
		Relation relation = this.image;
		if(relation.size() == 0)
			return null;
		long imageId = relation.getIds()[0];
		Image image = (Image)session.getById(Image.class, imageId);
		return image;
	}
	
	/**
	 * 让子类实现的检查配置是否合法的方法
	 * @throws ConfigureInvalidException
	 */
	public void checkConfig() throws ConfigureInvalidException {}
	/**
	 * 让所有的正常工作节点安装镜像, 处理容器
	 * @param nodes
	 * @throws Exception
	 */
	public void processContainer(Session session) throws Exception {}
	
	/**
	 * 获取关联的service对象
	 * @param session
	 * @return
	 * @throws Exception 
	 * @throws DocumentException 
	 * @throws UnsuportedFieldException 
	 */
	public Service getService(Session session) throws UnsuportedFieldException, DocumentException, Exception
	{
		Relation relation = this.getService();
		if(relation.size() == 0)
			return null;
		
		long serviceId = relation.getIds()[0];
		Service service = (Service)session.getById(Service.class, serviceId);
		return service;
	}
	
	public static String toDictString(Method m)
	{
		if(m.getName().equals("getImage"))
		{
			return "获取部署关联的镜像对象";
		}
		else if(m.getName().equals("checkConfig"))
		{
			return "检查配置是否合法";
		}
		else if(m.getName().equals("processContainer"))
		{
			return "处理部署关联的容器逻辑";
		}
		else if(m.getName().equals("getService"))
		{
			return "获取部署关联的服务";
		}
		return LogNode.toDictString(m);
	}

	
	public static String toDictString(Field f)
	{
		if(f.getName().equals("name"))
		{
			return "部署名称";
		}
		else if(f.getName().equals("description"))
		{
			return "部署描述";
		}
		else if(f.getName().equals("hostPort"))
		{
			return "部署服务端口";
		}
		else if(f.getName().equals("containerPort"))
		{
			return "部署容器应用端口";
		}
		else if(f.getName().equals("mode"))
		{
			return "部署模式: 0:无状态工作节点模式, 1: 主从模式, 2: 主从哨兵模式";
		}
		else if(f.getName().equals("curContainerPort"))
		{
			return "如果分配给容器应用的端口是靠服务递增的, 这个字段指示当前的端口值, 依容器创建递增";
		}
		else if(f.getName().equals("curId"))
		{
			return "用来分配部署唯一的id";
		}
		else if(f.getName().equals("tryCount"))
		{
			return "用来计数, 比如出错出现异常的次数, 减少误判";
		}
		else if(f.getName().equals("secondHostPort"))
		{
			return "用做一些服务需要提供两个对外端口的, 比如mysql读写分离";
		}
		else if(f.getName().equals("service"))
		{
			return "关联的服务";
		}
		else if(f.getName().equals("image"))
		{
			return "部署当前的版本镜像";
		}
		return LogNode.toDictString(f);
	}


	public int getCurContainerPort() {
		return curContainerPort;
	}

	public void setCurContainerPort(int curContainerPort) {
		this.curContainerPort = curContainerPort;
	}

	public int getSecondHostPort() {
		return secondHostPort;
	}

	public void setSecondHostPort(int secondHostPort) {
		this.secondHostPort = secondHostPort;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	

	public int getCurId() {
		return curId;
	}

	public void setCurId(int curId) {
		this.curId = curId;
	}

	public String getDescription() {
		return description.string;
	}

	public void setDescription(String description) {
		this.description.string = description;
	}

	public int getHostPort() {
		return hostPort;
	}

	public void setHostPort(int hostPort) {
		this.hostPort = hostPort;
	}

	public int getContainerPort() {
		return containerPort;
	}

	public void setContainerPort(int containerPort) {
		this.containerPort = containerPort;
	}

	public int getMode() {
		return mode;
	}

	public void setMode(int mode) {
		this.mode = mode;
	}
	
	public Relation getImage() {
		return image;
	}

	public Relation getService() {
		return service;
	}
	

	public int getTryCount() {
		return tryCount;
	}

	public void setTryCount(int tryCount) {
		this.tryCount = tryCount;
	}

	@Override
	public String toString() {
		return "Deployment [name=" + name + ", description=" + description + ", hostPort=" + hostPort
				+ ", secondHostPort=" + secondHostPort + ", containerPort=" + containerPort + ", curContainerPort="
				+ curContainerPort + ", curId=" + curId + ", mode=" + mode + ", tryCount=" + tryCount + ", service="
				+ service + ", image=" + image + ", _id=" + _id + ", _v=" + _v + "]";
	}
	
	
}
